package com.ipay.controller;

import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.*;

import com.ipay.core.HttpGateway;
import com.ipay.core.Param;
import com.ipay.entity.*;
import com.ipay.service.CashiersService;
import com.ipay.service.PayChannelService;
import com.ipay.service.TradeRecordService;
import com.ipay.service.impl.DefaultSequenceManager;
import com.ipay.utils.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jdom.CDATA;
import org.jdom.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import com.ipay.service.PayorderService;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

/**
 * 支付交易订单流水（支付、退款）
 *
 * @author hacken
 * @email hacken_hu@163.com
 * @date 2017-06-13 20:11:53
 */
@RestController
@RequestMapping("/payorder")
public class PayorderController extends AbstractController {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private PayorderService payorderService;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private TradeRecordService tradeRecordService;
    @Autowired
    private CashiersService cashiersService;
    @Autowired
    private PayChannelService payChannelService;
    @Autowired
    private HttpGateway gateway;

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("payorder:list")
    public R list(@RequestParam Map<String, Object> params, HttpServletRequest request) {
        //商户信息
        String merchantNo = getUser().getMerchantNo();
        params.put("busid", merchantNo);
        // 查询列表数据
        Query query = new Query(params);
        List<PayorderEntity> payorderList = payorderService.queryList(query);
        for (PayorderEntity payorderEntity : payorderList) {
            if (StringUtil.isNotEmpty(payorderEntity.getBankType())) {
                try {
                    payorderEntity.setBankTypeVue(Constant.BankType.valueOf(payorderEntity.getBankType()).getValue());
                } catch (IllegalArgumentException e) {
                    payorderEntity.setBankTypeVue(payorderEntity.getBankType());
                }
            }
        }
        int total = payorderService.queryTotal(query);

        PageUtils pageUtil = new PageUtils(payorderList, total, query.getLimit(), query.getPage());

        return R.ok().put("page", pageUtil);
    }

    /**
     * 订单详情
     */
    @RequestMapping("/info/{id}")
    //@RequiresPermissions("payorder:info")
    public R info(@PathVariable("id") String id) {
        PayorderEntity payorder = payorderService.queryObject(id);
        if (payorder != null && StringUtil.isNotEmpty(payorder.getRecordno())) {
            if (StringUtil.isNotEmpty(payorder.getBankType())) {
                try {
                    payorder.setBankTypeVue(Constant.BankType.valueOf(payorder.getBankType()).getValue());
                } catch (IllegalArgumentException e) {
                    payorder.setBankTypeVue(payorder.getBankType());
                }
            }
            if(StringUtil.isNotEmpty(payorder.getResource())) {
                payorder.setResourceVue(Constant.RESOURCE.get(payorder.getResource()));
            }
            ///查询订单是否申请的退款
            boolean bool = false;
            if (StringUtil.isNotEmpty(payorder.getRecordno())) {
                //查询下已退款金额
                Map<String, Object> mapTradeRec = new HashMap<>();
                mapTradeRec.put("orderId", payorder.getRecordno());
                BigDecimal refundSumAmount = tradeRecordService.findRefundSumAmount(mapTradeRec);
                if (refundSumAmount == null) {
                    refundSumAmount = BigDecimal.valueOf(0);
                }
                payorder.setRefybdAmount(refundSumAmount);
                if (refundSumAmount.compareTo(payorder.getAmount()) == -1) { //结果是:-1 小于,0 等于,1 大于
                    bool = true;
                }
            }
            //判断是否为当天
            Date date = new Date();
            SimpleDateFormat df = new SimpleDateFormat("MM-dd");
            String today = df.format(date);
            String orderDate = df.format(payorder.getOrderdate());
            long subTime = date.getTime() - payorder.getOrderdate().getTime();
            if ((!today.equals(orderDate)) && bool) {
                if (subTime > 3600000 * 3) {
                    bool = false;
                }
            }
            //今日交易金额
            Map<String, Object> mapDatetrade = new HashMap<>();
            mapDatetrade.put("busId", payorder.getBusid());
            BigDecimal todaySumAmount = tradeRecordService.findTodaySumAmountByBusId(mapDatetrade);
            if (todaySumAmount == null) {
                todaySumAmount = BigDecimal.valueOf(0);
            }
            if (payorder.getAmount().compareTo(todaySumAmount) == 1) { //结果是:-1 小于,0 等于,1 大于
                bool = false;
            }
            payorder.setTodayAmount(todaySumAmount);
            return R.ok().put("payorder", payorder).put("bool", bool);
        } else {
            return R.error("获取订单信息错误");
        }
    }

    /**
     * 商户订单统计
     * /payorder/orderCensus
     */
    @RequestMapping("/orderCensus")
    //@RequiresPermissions("payorder:info")
    public R orderCensus(@RequestParam int day, @RequestParam int type, HttpServletRequest request) {
        Map mapchart = new HashMap();
        String orderdateBegin = request.getParameter("orderdateBegin");
        String orderdateEnd = request.getParameter("orderdateEnd");
        ///获取日期区间段数据
        TradeRecord payorder = new TradeRecord();
        Map mapxAxis = new HashMap();
        List<String> xAxisList;
        if (day < 1) {
            String start = TimeUtils.getTimeByDay(new Date(), day);
            String end = sdf.format(new Date());
            xAxisList = TimeUtils.findDates(start, end);
            payorder.setDay((day - 1) * -1);
        } else {
            xAxisList = TimeUtils.findDates(orderdateBegin, orderdateEnd);
            payorder.setOrderdateBegin(orderdateBegin); //orderdateBegin
            payorder.setOrderdateEnd(orderdateEnd); //   orderdateEnd
        }
        mapxAxis.put("categories", xAxisList);
        mapchart.put("xAxis", mapxAxis);
        //商户信息
        String merchantNo = getUser().getMerchantNo();
        System.out.println("=============:" + merchantNo);
        payorder.setBusId(merchantNo);
        //tr.orderdate &gt;= #{orderdateBegin} and tr.orderdate &lt;= #{orderdateEnd}
        List<Map<String, Object>> dateGroupingList = tradeRecordService.findDateGrouping(payorder);
        //今日交易总和
        Map maptitle = new HashMap();
        List seriesList = new ArrayList();
        Map map = new HashMap();
        payorder.setGroupBy("resource");
        if (type == 1 || type == 5) {
            map.put("name", "交易金额总和");
            if (type == 5) {
                maptitle.put("text", "各收款员交易");
                payorder.setGroupBy("codeNo");
            } else {
                maptitle.put("text", "交易金额");
            }
        } else if (type == 2) {
            maptitle.put("text", "交易笔数");
            map.put("name", "交易笔数总和");
        } else if (type == 3) {
            maptitle.put("text", "退款金额");
            map.put("name", "退款金额总和");
        } else if (type == 4) {
            maptitle.put("text", "退款笔数");
            map.put("name", "退款笔数总和");
        }
        mapchart.put("title", maptitle);
        List list = new ArrayList<BigDecimal>();
        for (String dateFormat : xAxisList) {
            BigDecimal sumAmount = BigDecimal.valueOf(0);
            ;
            for (Map<String, Object> tradeRecord : dateGroupingList) {
                if (dateFormat.equals(tradeRecord.get("dateFormat"))) { // tradeRecord.getsumAmount
                    if (type == 1 || type == 5) {
                        sumAmount = MathUtil.getBigDecimal(tradeRecord.get("sumAmount"));
                    } else if (type == 2) {
                        sumAmount = MathUtil.getBigDecimal(tradeRecord.get("countId"));
                    } else if (type == 3) {
                        sumAmount = MathUtil.getBigDecimal(tradeRecord.get("refundAmount"));
                    } else if (type == 4) {
                        sumAmount = MathUtil.getBigDecimal(tradeRecord.get("countRefund"));
                    }
                }
            }
            list.add(sumAmount);
        }
        map.put("data", list);
        seriesList.add(map);
        ///详细交易订单信息（区分时间和来源【支付宝还是微信还是其他渠道】）
        List<Map<String, Object>> dateResourceList = tradeRecordService.findDateGrouping(payorder);
        if (type == 5) {
            Map mapchartPie = new HashMap();//扇形统计图处理
            List listTh = new ArrayList<BigDecimal>();//扇形统计图处理
            //查询收款员信息
            CashiersEntity cashiersEntity = new CashiersEntity();
            cashiersEntity.setMerchantId(merchantNo);
            List<Map<String, Object>> cashiersList = cashiersService.findCodeDataGrouping(cashiersEntity);//收款员信息查询
            for (Map<String, Object> cashiers : cashiersList) {
                Map mapOthe = new HashMap();
                List listTho = new ArrayList<Object>();//扇形统计图处理
                BigDecimal sumPayTypeAmount = BigDecimal.valueOf(0);//统计某个支付类型总金额

                List listOthe = new ArrayList<BigDecimal>();
                for (String dateFormat : xAxisList) { ///时间段
                    BigDecimal sumAmount = BigDecimal.valueOf(0);
                    if (StringUtil.isNotEmpty(cashiers.get("code_no"))) {
                        for (Map<String, Object> tradeRecord : dateResourceList) { //订单数据
                            if (dateFormat.equals(tradeRecord.get("dateFormat").toString()) &&
                                    cashiers.get("code_no").equals(tradeRecord.get("code_no").toString())) { ///时间+收款二维码编号
                                sumAmount = MathUtil.getBigDecimal(tradeRecord.get("sumAmount"));
                            }
                        }
                    }
                    listOthe.add(sumAmount);
                    if (sumAmount != null) {//扇形统计图处理
                        sumPayTypeAmount = sumPayTypeAmount.add(sumAmount);
                    }
                }
                //delete_status
                if (StringUtil.isNotEmpty(cashiers.get("code_name"))) {
                    if (StringUtil.isNotEmpty(cashiers.get("delete_status"))) {
                        if (Constant.DELETE_STATUS_YES.equals(cashiers.get("delete_status"))) {
                            listTho.add(cashiers.get("name") + "/" + cashiers.get("code_name") + "(已删除) 金额:" + sumPayTypeAmount);//扇形统计图处理
                            mapOthe.put("name", cashiers.get("name") + "/" + cashiers.get("code_name") + "(已删除)");
                        } else {
                            mapOthe.put("name", cashiers.get("name") + "/" + cashiers.get("code_name"));
                            listTho.add(cashiers.get("name") + "/" + cashiers.get("code_name") + "金额:" + sumPayTypeAmount);//扇形统计图处理
                        }
                    }
                } else {
                    mapOthe.put("name", cashiers.get("name"));
                    listTho.add(cashiers.get("name") + "金额:" + sumPayTypeAmount);//扇形统计图处理
                }
                listTho.add(sumPayTypeAmount);//扇形统计图处理
                listTh.add(listTho);//扇形统计图处理

                mapOthe.put("data", listOthe);
                seriesList.add(mapOthe);
            }
            mapchartPie.put("type", "pie");//扇形统计图处理
            mapchartPie.put("data", listTh);//扇形统计图处理
            List listPie = new ArrayList<BigDecimal>();//扇形统计图处理
            listPie.add(mapchartPie);//扇形统计图处理
            mapchart.put("pieSeries", listPie);//扇形统计图处理
        } else {
            Map mapchartPie = new HashMap();//扇形统计图处理
            List listTh = new ArrayList<BigDecimal>();//扇形统计图处理
            List seriesOthList = new ArrayList();


            Iterator<Map.Entry<String, String>> it = Constant.RESOURCE.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<String, String> m = it.next();
                String key = m.getKey();
                String value = m.getValue();

                List listTho = new ArrayList<Object>();//扇形统计图处理
                BigDecimal sumPayTypeAmount = BigDecimal.valueOf(0);//统计某个支付类型总金额
                String amaoutVue = "";
                Map mapOthe = new HashMap();
                mapOthe.put("name", value);
                List listOthe = new ArrayList<BigDecimal>();
                for (String dateFormat : xAxisList) {  //循环时间段
                    BigDecimal sumAmount = BigDecimal.valueOf(0);
                    for (Map<String, Object> tradeRecord : dateResourceList) {  //循环交易详细数据
                        if (dateFormat.equals(tradeRecord.get("dateFormat").toString()) && key.equals(tradeRecord.get("resource").toString())) { ///时间+支付来源
                            if (type == 1) {
                                amaoutVue = " 交易金额:";
                                sumAmount = MathUtil.getBigDecimal(tradeRecord.get("sumAmount"));
                            } else if (type == 2) {
                                amaoutVue = " 交易笔数:";
                                sumAmount = MathUtil.getBigDecimal(tradeRecord.get("countId"));
                            } else if (type == 3) {
                                amaoutVue = " 退款金额:";
                                sumAmount = MathUtil.getBigDecimal(tradeRecord.get("refundAmount"));
                            } else if (type == 4) {
                                amaoutVue = " 退款笔数:";
                                sumAmount = MathUtil.getBigDecimal(tradeRecord.get("countRefund"));
                            }
                        }
                    }
                    listOthe.add(sumAmount);
                    if (sumAmount != null) {//扇形统计图处理
                        sumPayTypeAmount = sumPayTypeAmount.add(sumAmount);
                    }
                }
                listTho.add(value + amaoutVue + sumPayTypeAmount);//扇形统计图处理
                listTho.add(sumPayTypeAmount);//扇形统计图处理
                listTh.add(listTho);//扇形统计图处理

                mapOthe.put("data", listOthe);
                seriesOthList.add(mapOthe);
                seriesList.add(mapOthe);
            }
            mapchart.put("seriesOth", seriesOthList);
            mapchartPie.put("type", "pie");//扇形统计图处理
            mapchartPie.put("data", listTh);//扇形统计图处理
            List listPie = new ArrayList<BigDecimal>();//扇形统计图处理
            listPie.add(mapchartPie);//扇形统计图处理
            mapchart.put("pieSeries", listPie);//扇形统计图处理
        }
        mapchart.put("series", seriesList);
        return R.ok().put("mapchart", mapchart);
    }

    /**
     * 各收款员天 交易信息导出
     * /payorder/orderCensus
     */
    @RequestMapping("/exportDate")
    public void exportDate(@RequestParam int day, HttpServletRequest request, HttpServletResponse response) {
        String orderdateBegin = request.getParameter("orderdateBegin");
        String orderdateEnd = request.getParameter("orderdateEnd");
        ///获取日期区间段数据
        TradeRecord payorder = new TradeRecord();
        List<String> xAxisList;
        if (day < 1) {
            String start = TimeUtils.getTimeByDay(new Date(), day);
            String end = sdf.format(new Date());
            xAxisList = TimeUtils.findDates(start, end);
            payorder.setDay((day - 1) * -1);
        } else {
            xAxisList = TimeUtils.findDates(orderdateBegin, orderdateEnd);
            payorder.setOrderdateBegin(orderdateBegin); //orderdateBegin
            payorder.setOrderdateEnd(orderdateEnd); //   orderdateEnd
        }
        //商户信息
        List<Map> seriesList = new ArrayList<Map>();
        String merchantNo = getUser().getMerchantNo();
        ///详细交易订单信息（区分时间和来源【支付宝还是微信还是其他渠道】）
        payorder.setBusId(merchantNo);
        payorder.setGroupBy("codeNo");
        List<Map<String, Object>> dateResourceList = tradeRecordService.findDateGrouping(payorder);
        //查询收款员信息
        CashiersEntity cashiersEntity = new CashiersEntity();
        cashiersEntity.setMerchantId(merchantNo);
        List<Map<String, Object>> cashiersList = cashiersService.findCodeDataGrouping(cashiersEntity);
        for (Map<String, Object> cashiers : cashiersList) { //收款员信息
            Map<String, Object> mapOthe = new HashMap<String, Object>();
            BigDecimal sumAmount = BigDecimal.valueOf(0);
            BigDecimal sumCountId = BigDecimal.valueOf(0);///时间段总 交易笔数
            BigDecimal sumCountRefund = BigDecimal.valueOf(0);///时间段总 退款笔数
            BigDecimal sumRefundAmount = BigDecimal.valueOf(0);///时间段总 退款金额
            BigDecimal sumGatheringAmount = BigDecimal.valueOf(0);///时间段总 收款金额
            if (StringUtil.isNotEmpty(cashiers.get("code_name"))) {
                mapOthe.put("name", cashiers.get("name") + "/" + cashiers.get("code_name"));
            } else {
                mapOthe.put("name", cashiers.get("name"));
            }
            List<BigDecimal> listOthe = new ArrayList<BigDecimal>();
            for (String dateFormat : xAxisList) { //日期段
                BigDecimal sumDayAmount = BigDecimal.valueOf(0);
                BigDecimal sumDayCountId = BigDecimal.valueOf(0);///天 交易笔数
                BigDecimal sumDayCountRefund = BigDecimal.valueOf(0);///天 退款笔数
                BigDecimal sumDayRefundAmount = BigDecimal.valueOf(0);///天 退款金额
                BigDecimal sumDayGatheringAmount = BigDecimal.valueOf(0);///天 收款金额
                if (StringUtil.isNotEmpty(cashiers.get("code_no"))) {
                    for (Map<String, Object> tradeRecord : dateResourceList) { //订单数据
                        if (dateFormat.equals(tradeRecord.get("dateFormat").toString()) &&
                                cashiers.get("code_no").equals(tradeRecord.get("code_no").toString())) { ///时间+收款二维码编号
                            sumDayAmount = MathUtil.getBigDecimal(tradeRecord.get("sumAmount"));//交易金额总和
                            if (sumDayAmount == null) {
                                sumDayAmount = BigDecimal.valueOf(0);
                            }
                            sumDayCountId = MathUtil.getBigDecimal(tradeRecord.get("sumCountId"));//交易笔数(有效笔数 即订单状态是成功的【pay_result支付结果：0—成功】)
                            if (sumDayCountId == null) {
                                sumDayCountId = BigDecimal.valueOf(0);
                            }
                            sumDayCountRefund = MathUtil.getBigDecimal(tradeRecord.get("countRefund"));//退款笔数
                            if (sumDayCountRefund == null) {
                                sumDayCountRefund = BigDecimal.valueOf(0);
                            }
                            sumDayRefundAmount = MathUtil.getBigDecimal(tradeRecord.get("refundAmount"));//退款金额
                            if (sumDayRefundAmount == null) {
                                sumDayRefundAmount = BigDecimal.valueOf(0);
                            }
                            sumDayGatheringAmount = MathUtil.getBigDecimal(tradeRecord.get("gatheringAmount"));//收款金额
                            if (sumDayGatheringAmount == null) {
                                sumDayGatheringAmount = BigDecimal.valueOf(0);
                            }
                            //sumAmount交易金额总和  countId交易笔数  gatheringAmount收款金额   refundAmount退款金额   countRefund退款笔数
                        }
                    }
                }
                listOthe.add(sumDayAmount);

                sumAmount = sumAmount.add(sumDayAmount);
                sumCountId = sumCountId.add(sumDayCountId);
                sumCountRefund = sumCountRefund.add(sumDayCountRefund);
                sumRefundAmount = sumRefundAmount.add(sumDayRefundAmount);
                sumGatheringAmount = sumGatheringAmount.add(sumDayGatheringAmount);
            }
            listOthe.add(sumAmount);//总计
            listOthe.add(sumGatheringAmount);//收款金额
            listOthe.add(sumRefundAmount);//退款金额
            listOthe.add(sumCountId);//总笔数
            listOthe.add(sumCountRefund);//退款笔数
            ///当年历史订单总额  当月总额  当日总额
            if (StringUtil.isNotEmpty(cashiers.get("code_no"))) {
                payorder.setCodeNo(String.valueOf(cashiers.get("code_no")));//收款员编号---setBusId---setCodeNo---setOrderdateType
                listOthe.add(findOrderDateStatistics(payorder, ""));//历史订单总金额
                //按时间查询区分类型  历史交易金额 days当天  dateFormat当月  quarter季度  year年
                listOthe.add(findOrderDateStatistics(payorder, "days"));//当天订单总金额
                listOthe.add(findOrderDateStatistics(payorder, "dateFormat"));//当月订单总金额
                listOthe.add(findOrderDateStatistics(payorder, "quarter"));//季度 订单总金额
                listOthe.add(findOrderDateStatistics(payorder, "year"));//年订单总金额
            } else {
                listOthe.add(BigDecimal.valueOf(0));
                listOthe.add(BigDecimal.valueOf(0));
                listOthe.add(BigDecimal.valueOf(0));
                listOthe.add(BigDecimal.valueOf(0));
                listOthe.add(BigDecimal.valueOf(0));
            }
            mapOthe.put("data", listOthe);
            seriesList.add(mapOthe);
        }
        String fileName = "收款员交易数据";
        String excelRoot = Utils.getUploadPath(request);
        String file = "/" + System.currentTimeMillis() + ".xls";
        xAxisList.add(0, "");
        int size = xAxisList.size();

        String[] arr = (String[]) xAxisList.toArray(new String[size + 10]);//使用了第二种接口，返回值和参数均为结果
        arr[size] = "总计";
        arr[size + 1] = "收款金额";
        arr[size + 2] = "退款金额";
        arr[size + 3] = "总笔数(有效)";
        arr[size + 4] = "退款笔数";
        //历史交易金额 days当天  dateFormat当月  quarter季度  year年
        arr[size + 5] = "历史总额";
        arr[size + 6] = "当天总额";
        arr[size + 7] = "当月总额";
        arr[size + 8] = "本季度总额";
        arr[size + 9] = "当年总额";

        tradeRecordService.exportExcel(arr, excelRoot + file, seriesList);
        response.setContentType("application/x-msdownload");
        fileName = fileName + System.currentTimeMillis();//
        FileInputStream fis=null;
        try {
            fileName = new String(fileName.getBytes("gb2312"), "ISO8859-1");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xls");
            ServletOutputStream sos = response.getOutputStream();
            fis = new FileInputStream(excelRoot + file);
            int flag = 0;
            byte[] buff = new byte[1024 * 4];
            while ((flag = fis.read(buff, 0, buff.length)) != -1) {
                sos.write(buff, 0, flag);
            }
            fis.close();
            sos.close();
        } catch (IOException e) {
            throw new NullPointerException("下载出现错误！");
        }finally {
            if(fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private BigDecimal findOrderDateStatistics(TradeRecord payorder, String orderdateType) {
        payorder.setOrderdateType(orderdateType);
        List<Map<String, Object>> tradeRecordMap = tradeRecordService.findOrderDateStatistics(payorder);//历史订单总金额
        if (tradeRecordMap != null && tradeRecordMap.size() == 1) {
            Map<String, Object> tradeMap = tradeRecordMap.get(0);
            BigDecimal sumAmt = MathUtil.getBigDecimal(tradeMap.get("sumAmount"));//交易金额总和
            if (sumAmt == null) {
                sumAmt = BigDecimal.valueOf(0);
            }
            return sumAmt;
        } else {
            return BigDecimal.valueOf(0);
        }
    }

    /**
     * 退款处理
     */
    @RequestMapping("/orderRefund")
    public R orderRefund(@RequestBody String id) {
        logger.info("=====退款处理=====" + id);
        PayorderEntity payorder = payorderService.queryObject(id);
        if (payorder == null || StringUtil.isBlank(payorder.getRecordno())) {
            return R.error("退款订单信息错误");
        }
        // 构建退款交易
        String refundNo = DefaultSequenceManager.get().next(BizSequenceType.TRANSQ);//生成退款订单号
        PayorderEntity refundObj = new PayorderEntity();
        refundObj.setOrderid(payorder.getRecordno());
        refundObj.setAmount(payorder.getAmount());
        refundObj.setCategory(Constant.CATEGORY_TK);
        refundObj.setRecordno(refundNo);//设置：退款订单号
        refundObj.setBusid(payorder.getBusid());
        refundObj.setOrderdate(new Date());
        refundObj.setResource(payorder.getResource());
        refundObj.setRefundtype("1");// 全额退款
        refundObj.setCodeNo(payorder.getCodeNo());
        refundObj.setStatus(Constant.STATUS_WZ);
        refundObj.setPayResult(Constant.PAY_RESULT_ERROR);
        refundObj.setMchCreateIp(IPUtils.getIpAddr(request));
        ///查询下商户收款参数信息
        Map<String, Object> mapPayChannel = new HashMap<String, Object>();
        mapPayChannel.put("merchantNo", payorder.getBusid());
        mapPayChannel.put("payState", Constant.Status.ENABLE.getValue());//状态 0、删除 1、启用 2、禁用
        if (payorder.getResource() != null && payorder.getResource().equals(Constant.Resource.RESOURCE_WX.getValue())) {//获取：来源（0 微信、1 支付宝）
            mapPayChannel.put("payType", Constant.PayType.PAY_WX.getValue());//微信
        } else if (payorder.getResource() != null && payorder.getResource().equals(Constant.Resource.RESOURCE_ZFB.getValue())) {
            mapPayChannel.put("payType", Constant.PayType.PAY_ZFB.getValue());//支付宝
        }
        PayChannelEntity payChannel = payChannelService.queryPayBymerchantNo(mapPayChannel);
        if (payChannel == null || StringUtil.isEmpty(payChannel.getPayChannelNo()) || StringUtil.isEmpty(payChannel.getPayKey())) {
            return R.error("商户渠道参数错误");
        }
        refundObj.setPaychannelId(payChannel.getPayChannelId());
        //退款参数组装处理
        Map<String, String> map = gatewayPayInit(refundObj, payorder.getTransactionId());
        map.put("mch_id", payChannel.getPayChannelNo());
        String strtosign = MapUtils.formatUrlMap(map, false, false);
        String signstr = MD5.sign(strtosign, "&key=" + payChannel.getPayKey(), "utf-8");
        map.put("sign", signstr);
        Param param = Param.create();
        param.putAll(map);
        // 退款接口
        try {
            //今日交易金额
            Map<String, Object> mapDatetrade = new HashMap<>();
            mapDatetrade.put("busId", payorder.getBusid());
            BigDecimal todaySumAmount = tradeRecordService.findTodaySumAmountByBusId(mapDatetrade);
            if (todaySumAmount == null) {
                todaySumAmount = BigDecimal.valueOf(0);
            }
            if (payorder.getAmount().compareTo(todaySumAmount) == 1) { //结果是:-1 小于,0 等于,1 大于
                logger.error("当日交易金额小于退款金额，无法进行退款处理,订单号：【" + payorder.getRecordno() + "】  订单金额：【" + payorder.getAmount() + "】今日交易金额：【" + todaySumAmount + "】");
                return R.error("当日交易金额小于退款金额，无法进行退款处理");
            }

            refundObj.setLaunchMode(payorder.getLaunchMode());
            payorderService.save(refundObj);
            gateway.url = "https://pay.swiftpass.cn/pay/gateway";
            Param resultparam = gateway.post(param);
            logger.info("===退款返回字符串：" + resultparam.toString());
            String status = resultparam.get("status");
            if (status.equals("0")) { // 成功
                String result_code = resultparam.get("result_code");// 业务成功结果
                if (result_code.equals("0")) {
                    System.out.println(refundObj.getOrderid() + "  =  " + resultparam.get("out_refund_no"));
                    if (refundObj.getRecordno().equals(resultparam.get("out_refund_no"))) {
                        //平台退款单号  refund_id
                        refundObj.setRefundId(resultparam.get("refund_id"));//平台退款单号
                        refundObj.setRefundChannel(resultparam.get("refund_channel"));//退款渠道
                        refundObj.setPayResult(Integer.valueOf(result_code));
                        refundObj.setStatus(Constant.STATUS_PROCESSING);//退款处理中；
                        payorderService.update(refundObj);
                    }
                } else {
                    refundObj.setRemark(resultparam.get("err_msg"));
                    payorderService.update(refundObj);
                    return R.error(refundObj.getRemark());
                }
            } else {
                refundObj.setRemark(resultparam.get("message"));
                payorderService.update(refundObj);
                return R.error(refundObj.getRemark());
            }
        } catch (Exception e) {
            logger.error("银行通讯失败", e);
            refundObj.setRemark("银行通讯失败");
            payorderService.update(refundObj);
            return R.error(refundObj.getRemark());
        }
        return R.ok();
    }

    /**
     * 组装退款参数
     *
     * @param payorder      退款订单参数
     * @param transactionId 支付订单-威富通订单号
     * @return
     */
    private Map<String, String> gatewayPayInit(PayorderEntity payorder, String transactionId) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("service", "unified.trade.refund");
        map.put("version", "2.0");
        map.put("charset", "UTF-8");
        map.put("sign_type", "MD5");
        //商户订单号  -TODO 与 威富通订单号必须有一个存在
        map.put("out_trade_no", payorder.getOrderid().toString());
        //威富通订单号
        map.put("transaction_id", transactionId);
        map.put("out_refund_no", payorder.getRecordno());//商户退款单号
        BigDecimal totalFee = payorder.getAmount().multiply(BigDecimal.valueOf(100));
        map.put("total_fee", Utils.round(totalFee, 0).toString());//总金额
        BigDecimal refundFee = payorder.getAmount().multiply(BigDecimal.valueOf(100));
        map.put("refund_fee", Utils.round(refundFee, 0).toString());//退款金额
        map.put("op_user_id", payorder.getBusid());//操作员帐号,默认为商户号
        map.put("nonce_str", RandomStringUtils.getRandomStringByLength(32));
        map.put("refund_channel", "ORIGINAL");
        return map;
    }


    /**
     * 收款员 比对
     * /payorder/orderCensus
     */
    @RequestMapping("/orderContrast")
    //@RequiresPermissions("payorder:info")
    public R orderContrast(@RequestParam int day, @RequestParam int type, HttpServletRequest request) {
        Map mapchart = new HashMap();
        Map mapTjlb = new HashMap();//头部列表数据
        String orderdateBegin = request.getParameter("orderdateBegin");//开始时间
        String orderdateEnd = request.getParameter("orderdateEnd");//结束时间
        String userIds = request.getParameter("userIds");//收款员
        ///获取日期区间段数据
        TradeRecord payorder = new TradeRecord();
        Map mapxAxis = new HashMap();
        List<String> xAxisList;
        if (day < 1) { //处理 一周 或 一月数据
            String start = TimeUtils.getTimeByDay(new Date(), day);
            String end = sdf.format(new Date());
            xAxisList = TimeUtils.findDates(start, end);
            payorder.setDay((day - 1) * -1);
        } else {
            xAxisList = TimeUtils.findDates(orderdateBegin, orderdateEnd);
            payorder.setOrderdateBegin(orderdateBegin); //orderdateBegin
            payorder.setOrderdateEnd(orderdateEnd); //   orderdateEnd
        }
        mapxAxis.put("categories", xAxisList);
        mapchart.put("xAxis", mapxAxis);
        String merchantNo = getUser().getMerchantNo();//商户信息
        System.out.println("======商户信息编号=======:" + merchantNo);
        payorder.setBusId(merchantNo);
        //今日交易总和
        Map maptitle = new HashMap();
        List seriesList = new ArrayList();
        maptitle.put("text", "各收款员交易");
        mapchart.put("title", maptitle);

        ///详细交易订单信息（区分时间和来源【支付宝还是微信还是其他渠道】）
        payorder.setGroupBy("codeNo");
        payorder.setGroupBy("resource");
        if (StringUtil.isNotEmpty(userIds)) {
            String[] userIdStr = userIds.split(",");
            List<String> userIdList = Arrays.asList(userIdStr);
            payorder.setCashiersIdList(userIdList);
        }
        List<Map<String, Object>> dateResourceList = tradeRecordService.findDateGroupingSKY(payorder);
        Map mapchartPie = new HashMap();//扇形统计图处理
        List listTh = new ArrayList<BigDecimal>();//扇形统计图处理
        //查询收款员信息
        CashiersEntity cashiersEntity = new CashiersEntity();
        cashiersEntity.setMerchantId(merchantNo);
        if (StringUtil.isNotEmpty(userIds)) {
            String[] userIdStr = userIds.split(",");
            List<String> userIdList = Arrays.asList(userIdStr);
            cashiersEntity.setCashiersIdList(userIdList);
        }
        List<Map<String, Object>> cashiersList = cashiersService.findCodeDataGrouping(cashiersEntity);//收款员信息查询
        if (cashiersList != null) {
            for (Map<String, Object> cashiers : cashiersList) {
                Map mapOthe = new HashMap();
                BigDecimal sumCountId = BigDecimal.valueOf(0);///时间段总 交易笔数
                BigDecimal sumCountRefund = BigDecimal.valueOf(0);///时间段总 退款笔数
                BigDecimal sumRefundAmount = BigDecimal.valueOf(0);///时间段总 退款金额
                BigDecimal sumGatheringAmount = BigDecimal.valueOf(0);///时间段总 收款金额
                List listTho = new ArrayList<Object>();//扇形统计图处理
                BigDecimal sumPayTypeAmount = BigDecimal.valueOf(0);//统计某个支付类型总金额
                List listOthe = new ArrayList<BigDecimal>();
                for (String dateFormat : xAxisList) { ///时间段
                    BigDecimal sumDayAmount = BigDecimal.valueOf(0);
                    BigDecimal sumDayCountId = BigDecimal.valueOf(0);///天 交易笔数
                    BigDecimal sumDayCountRefund = BigDecimal.valueOf(0);///天 退款笔数
                    BigDecimal sumDayRefundAmount = BigDecimal.valueOf(0);///天 退款金额
                    BigDecimal sumDayGatheringAmount = BigDecimal.valueOf(0);///天 收款金额
                    BigDecimal sumAmount = BigDecimal.valueOf(0);
                    if (StringUtil.isNotEmpty(cashiers.get("code_no"))) {
                        for (Map<String, Object> tradeRecord : dateResourceList) { //订单数据
                            if (dateFormat.equals(tradeRecord.get("dateFormat").toString()) &&
                                    cashiers.get("code_no").equals(tradeRecord.get("code_no").toString())) { ///时间+收款二维码编号
                                sumAmount = MathUtil.getBigDecimal(tradeRecord.get("sumAmount"));
                                sumDayAmount = MathUtil.getBigDecimal(tradeRecord.get("sumAmount"));//交易金额总和
                                if (sumDayAmount == null) {
                                    sumDayAmount = BigDecimal.valueOf(0);
                                }
                                sumDayCountId = MathUtil.getBigDecimal(tradeRecord.get("sumCountId"));//交易笔数(有效笔数 即订单状态是成功的【pay_result支付结果：0—成功】)
                                if (sumDayCountId == null) {
                                    sumDayCountId = BigDecimal.valueOf(0);
                                }
                                sumDayCountRefund = MathUtil.getBigDecimal(tradeRecord.get("countRefund"));//退款笔数
                                if (sumDayCountRefund == null) {
                                    sumDayCountRefund = BigDecimal.valueOf(0);
                                }
                                sumDayRefundAmount = MathUtil.getBigDecimal(tradeRecord.get("refundAmount"));//退款金额
                                if (sumDayRefundAmount == null) {
                                    sumDayRefundAmount = BigDecimal.valueOf(0);
                                }
                                sumDayGatheringAmount = MathUtil.getBigDecimal(tradeRecord.get("gatheringAmount"));//收款金额
                                if (sumDayGatheringAmount == null) {
                                    sumDayGatheringAmount = BigDecimal.valueOf(0);
                                }
                            }
                        }
                    }
                    listOthe.add(sumAmount);
                    if (sumAmount != null) {//扇形统计图处理
                        sumPayTypeAmount = sumPayTypeAmount.add(sumAmount);
                    }
                    sumCountId = sumCountId.add(sumDayCountId);
                    sumCountRefund = sumCountRefund.add(sumDayCountRefund);
                    sumRefundAmount = sumRefundAmount.add(sumDayRefundAmount);
                    sumGatheringAmount = sumGatheringAmount.add(sumDayGatheringAmount);
                }
                if (StringUtil.isNotEmpty(cashiers.get("code_name"))) {
                    if (StringUtil.isNotEmpty(cashiers.get("delete_status"))) {
                        if (Constant.DELETE_STATUS_YES.equals(cashiers.get("delete_status"))) {
                            listTho.add(cashiers.get("name") + "/" + cashiers.get("code_name") + "(已删除) 金额:" + sumPayTypeAmount);//扇形统计图处理
                            mapOthe.put("name", cashiers.get("name") + "/" + cashiers.get("code_name") + "(已删除)");
                        } else {
                            mapOthe.put("name", cashiers.get("name") + "/" + cashiers.get("code_name"));
                            listTho.add(cashiers.get("name") + "/" + cashiers.get("code_name") + "金额:" + sumPayTypeAmount);//扇形统计图处理
                        }
                    }
                } else {
                    mapOthe.put("name", cashiers.get("name"));
                    listTho.add(cashiers.get("name") + "金额:" + sumPayTypeAmount);//扇形统计图处理
                }
                listTho.add(sumPayTypeAmount);//扇形统计图处理
                listTh.add(listTho);//扇形统计图处理

                mapOthe.put("data", listOthe);
                seriesList.add(mapOthe);

                //////收款员对比头部统计
                if (cashiersList.size() == 1) {
                    mapTjlb.put("amountBool", true);//控制是否展现顶部数据列表
                    mapTjlb.put("sumAmount", sumPayTypeAmount);//总计
                    mapTjlb.put("sumGatheringAmount", sumGatheringAmount);//收款金额
                    mapTjlb.put("sumRefundAmount", sumRefundAmount);//退款金额
                    mapTjlb.put("sumCountId", sumCountId);//总笔数
                    mapTjlb.put("sumCountRefund", sumCountRefund);//退款笔数
                    if (StringUtil.isNotEmpty(cashiers.get("code_no"))) {
                        payorder.setCodeNo(String.valueOf(cashiers.get("code_no")));//收款员编号---setBusId---setCodeNo---setOrderdateType
                        mapTjlb.put("sum", findOrderDateStatistics(payorder, ""));//历史订单总金额
                        //按时间查询区分类型  历史交易金额 days当天  dateFormat当月  quarter季度  year年
                        mapTjlb.put("days", findOrderDateStatistics(payorder, "days"));//当天订单总金额
                        mapTjlb.put("dateFormat", findOrderDateStatistics(payorder, "dateFormat"));//当月订单总金额
                        mapTjlb.put("quarter", findOrderDateStatistics(payorder, "quarter"));//季度 订单总金额
                        mapTjlb.put("year", findOrderDateStatistics(payorder, "year"));//年订单总金额
                    }
                } else {
                    mapTjlb.put("amountBool", false);
                }
            }
        }
        mapchartPie.put("type", "pie");//扇形统计图处理
        mapchartPie.put("data", listTh);//扇形统计图处理
        List listPie = new ArrayList<BigDecimal>();//扇形统计图处理
        listPie.add(mapchartPie);//扇形统计图处理
        mapchart.put("pieSeries", listPie);//扇形统计图处理

        mapchart.put("series", seriesList);
        mapchart.put("listTjlb", mapTjlb);
        return R.ok().put("mapchart", mapchart);
    }

}
